Skip to content

[codex] Add Windows TSF IME insertion support#214

Closed
millionart wants to merge 37 commits into
Open-Less:mainfrom
millionart:codex-fix-windows-ime-x86-registration
Closed

[codex] Add Windows TSF IME insertion support#214
millionart wants to merge 37 commits into
Open-Less:mainfrom
millionart:codex-fix-windows-ime-x86-registration

Conversation

@millionart
Copy link
Copy Markdown
Contributor

@millionart millionart commented May 3, 2026

User description

Summary

Adds Windows TSF IME insertion support so OpenLess can commit dictated text through the active Windows text service instead of relying only on non-TSF fallback paths.

This PR also hardens the Windows packaging and registration flow:

  • builds and registers both x64 and Win32 OpenLess IME DLLs
  • registers COM/TSF using the correct 64-bit and 32-bit registry views
  • uses side-by-side registration staging paths so running host apps cannot lock the next build output
  • packages both IME DLLs into the Windows MSI
  • restores the previous IME profile after prepared insertion sessions

Fixes Included

  • Battle.net: supports 32-bit host processes by building and registering the Win32 IME DLL.
  • Microsoft Word: retries TF_E_SYNCHRONOUS rejections with an async TSF edit session.
  • Microsoft Word: moves the caret to the end of inserted text after commit by collapsing the committed range and setting selection.

Validation

  • node scripts/windows-package-msvc.test.mjs
  • x64 OpenLessIme.dll Release build: 0 warnings, 0 errors
  • Win32 OpenLessIme.dll Release build: 0 warnings, 0 errors
  • Local Battle.net manual test: text commits successfully
  • Local Microsoft Word manual test: text commits successfully and caret lands after inserted text

PR Type

Enhancement, Bug fix, Tests


Description

  • Add session-aware Windows TSF insertion flow

  • Restore IME profile after canceled sessions

  • Gate non-TSF fallback behind preference

  • Expose IME status, packaging, and tests


Diagram Walkthrough

flowchart LR
  A["Settings preference"] -- "toggle fallback" --> B["Coordinator session flow"]
  B -- "prepare / submit / restore" --> C["Windows IME session controller"]
  C -- "capture profile" --> D["TSF profile manager"]
  C -- "send text" --> E["IME IPC protocol"]
  E -- "pipe submit" --> F["OpenLess IME DLL"]
  C -- "status" --> G["Settings UI"]
Loading

File Walkthrough

Relevant files
Enhancement
25 files
coordinator.rs
Make session lifecycle IME-aware                                                 
+391/-47
windows_ime_profile.rs
Manage TSF profile capture and restore                                     
+660/-0 
windows_ime_ipc.rs
Add named-pipe IME submission transport                                   
+414/-0 
windows_ime_session.rs
Coordinate TSF preparation, submit, restore                           
+224/-0 
windows_ime_protocol.rs
Define IME pipe messages and names                                             
+173/-0 
lib.rs
Expose IME command and modules                                                     
+28/-9   
types.rs
Add Windows IME status and fallback pref                                 
+42/-2   
insertion.rs
Add Windows Unicode keystroke fallback                                     
+66/-6   
commands.rs
Expose Windows IME status command                                               
+6/-1     
Settings.tsx
Add Windows IME controls to settings                                         
+48/-0   
zh-CN.ts
Translate Windows IME settings strings                                     
+12/-0   
en.ts
Add English Windows IME copy                                                         
+12/-0   
ipc.ts
Mock Windows IME status in client                                               
+13/-0   
types.ts
Add Windows IME status interfaces                                               
+15/-0   
ipc_client.cpp
Implement IME client pipe communication                                   
+511/-0 
registry.cpp
Handle IME registry keys and paths                                             
+307/-0 
text_service.cpp
Implement TSF text service behavior                                           
+332/-0 
edit_session.cpp
Manage IME edit sessions and commits                                         
+125/-0 
class_factory.cpp
Expose IME COM class factory                                                         
+75/-0   
text_service.h
Declare TSF text service interface                                             
+54/-0   
dllmain.cpp
Initialize IME DLL entry points                                                   
+54/-0   
edit_session.h
Declare IME edit session helpers                                                 
+43/-0   
ipc_client.h
Declare IME IPC client interface                                                 
+37/-0   
class_factory.h
Declare IME class factory types                                                   
+20/-0   
registry.h
Declare IME registry helper functions                                       
+6/-0     
Formatting
2 files
hotkey.rs
Reformat hotkey handlers and flag updates                               
+20/-11 
selection.rs
Reflow Windows paste input imports                                             
+4/-3     
Tests
3 files
windows-real-asr-insertion-smoke.ps1
Support Win32 edit host smoke tests                                           
+76/-7   
windows-smoke-suite.ps1
Extend smoke suite with Win32 edit                                             
+2/-2     
windows-package-msvc.test.mjs
Test Windows packaging and registration                                   
+107/-0 
Configuration changes
13 files
windows-package-msvc.ps1
Package Windows IME artifacts and MSI                                       
+316/-0 
windows-ime-build.ps1
Build Windows IME DLL artifacts                                                   
+82/-0   
windows-ime-register.ps1
Register Windows IME COM and TSF                                                 
+78/-0   
windows-ime-unregister.ps1
Remove Windows IME registration entries                                   
+65/-0   
OpenLessIme.vcxproj
Configure IME DLL project settings                                             
+159/-0 
openless-ime.wxs
Bundle IME DLLs into MSI                                                                 
+54/-0   
OpenLessIme.sln
Add Windows IME solution entry                                                     
+27/-0   
resource.rc
Add IME version and resources                                                       
+33/-0   
guids.h
Define COM and TSF GUIDs                                                                 
+21/-0   
windows-package-msvc.cmd
Wrap Windows package build script                                               
+8/-0     
windows-preflight.ps1
Add Windows packaging preflight checks                                     
+63/-1   
tauri.conf.json
Update Tauri bundling and commands                                             
+11/-0   
OpenLessIme.def
Export IME DLL COM symbols                                                             
+6/-0     
Documentation
2 files
2026-05-01-windows-temporary-tsf-ime.md
Document temporary TSF IME rollout plan                                   
+2191/-0
2026-05-01-windows-temporary-tsf-ime-design.md
Document TSF IME design details                                                   
+143/-0 
Dependencies
1 files
Cargo.toml
Add Windows IME crate dependencies                                             
+7/-2     

millionart added 30 commits May 1, 2026 18:05
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Broken profile restore

Saving profile.clsid and profile.guidProfile with Debug formatting makes the captured text-service snapshot non-round-trippable. restore_profile() later parses those fields as GUID strings, so restoring the original IME profile after a TSF session will fail for any text-service profile, and the active-profile check can also stop recognizing OpenLess as active.

if profile.dwProfileType == TF_PROFILETYPE_INPUTPROCESSOR {
    Ok(ImeProfileSnapshot::text_service(
        profile.langid,
        format!("{:?}", profile.clsid),
        format!("{:?}", profile.guidProfile),
    ))
} else {
    keyboard_layout_snapshot_from_tsf(profile.langid, profile.hkl)
}

@millionart millionart deleted the codex-fix-windows-ime-x86-registration branch May 8, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant